/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.hamacekj.geometr.internalplugins;

import cz.hamacekj.geometr.Point;
import cz.hamacekj.geometr.PointObject;
import cz.hamacekj.geometr.SegmentObject;
import cz.hamacekj.geometr.plugin.ConstructionObject;
import cz.hamacekj.geometr.plugin.ConstructionPlugin;
import cz.hamacekj.geometr.plugin.IPoint;
import cz.hamacekj.geometr.plugin.IPointObject;
import cz.hamacekj.geometr.plugin.ISegmentObject;
import cz.hamacekj.geometr.plugin.InputParameters;
import cz.hamacekj.geometr.plugin.InputParametersInterface;
import cz.hamacekj.geometr.plugin.ParameterItem;
import cz.hamacekj.geometr.plugin.ParameterObject;
import cz.hamacekj.geometr.plugin.ParameterString;
import cz.hamacekj.geometr.plugin.ParameterValue;
import cz.hamacekj.geometr.plugin.PrimitiveObject;
import cz.hamacekj.geometr.plugin.ValueArgument;
import java.util.HashSet;
import java.util.Set;
import javax.swing.ImageIcon;

/**
 * Plugin pro vytvoření úsečky.
 * @author hamacekh
 */
public class SegmentPlugin implements ConstructionPlugin {

    private String error;
    
    @Override
    public String getPluginName() {
        return "Úsečka";
    }

    @Override
    public InputParametersInterface[] getPossibleParameters() {
        InputParametersInterface[] params = new InputParametersInterface[2];
        params[0] = new TwoPointsParameters();
        params[1] = new FirstSegmentParam();
        return params;
    }

    @Override
    public ImageIcon getIcon() {
        return new ImageIcon("images/usecka.png");
    }

    @Override
    public ConstructionObject[] createConstructionObject(InputParametersInterface parametersType, ConstructionObject[] objects, ValueArgument[] values) {
        if(parametersType instanceof TwoPointsParameters){
            final String labela = objects[0].getLabel();
            final String labelb = objects[1].getLabel();
            IPointObject a = (IPointObject)(objects[0].getPrimitiveObjects().toArray()[0]);
            IPointObject b = (IPointObject)(objects[1].getPrimitiveObjects().toArray()[0]);
            final IPoint fst = a.getPoint();
            final IPoint snd = b.getPoint();
            ISegmentObject seg = new ISegmentObject() {
                @Override
                public IPoint getA() {
                    return fst;
                }

                @Override
                public IPoint getB() {
                    return snd;
                }
            };
            final Set<PrimitiveObject> set = new HashSet<>();
            set.add(seg);
            ConstructionObject segment = new ConstructionObject() {

                @Override
                public String getLabel() {
                    return labela+labelb;
                }

                @Override
                public boolean isLabelShown() {
                    return false;
                }

                @Override
                public Set<PrimitiveObject> getPrimitiveObjects() {
                    return set;
                }

                @Override
                public String getStepDescription() {
                    return "<Úsečka> "+labela+labelb;
                }
            };
            ConstructionObject[] res = new ConstructionObject[1];
            res[0] = segment;
            return res;
        }
        if(parametersType instanceof FirstSegmentParam){
            final String alabel = values[0].getRealInput();
            final String blabel = values[1].getRealInput();
            if (!alabel.matches("^[A-Z][0-9]*$") || !blabel.matches("^[A-Z][0-9]*$")){
                this.error = "Krajní body se musí jmenovat jedním velkým písmenem "
                        + "s případným číselným indexem.";
                return null;
            }
            final double length = values[2].getValue();
            Point apoint = new Point(0, 0);
            Point bpoint = new Point(length, 0);
            IPointObject a = new PointObject(apoint);
            IPointObject b = new PointObject(bpoint);
            ISegmentObject seg = new SegmentObject(apoint, bpoint);
            final Set<PrimitiveObject> aset = new HashSet<>();
            aset.add(a);
            final Set<PrimitiveObject> bset = new HashSet<>();
            bset.add(b);
            final Set<PrimitiveObject> segset = new HashSet<>();
            segset.add(seg);
            ConstructionObject X = new ConstructionObject() {

                @Override
                public String getLabel() {
                    return alabel;
                }

                @Override
                public boolean isLabelShown() {
                    return true;
                }

                @Override
                public Set<PrimitiveObject> getPrimitiveObjects() {
                    return aset;
                }

                @Override
                public String getStepDescription() {
                    return "";
                }
            };
            ConstructionObject Y = new ConstructionObject() {

                @Override
                public String getLabel() {
                    return blabel;
                }

                @Override
                public boolean isLabelShown() {
                    return true;
                }

                @Override
                public Set<PrimitiveObject> getPrimitiveObjects() {
                    return bset;
                }

                @Override
                public String getStepDescription() {
                    return "";
                }
            };
            ConstructionObject XY = new ConstructionObject() {

                @Override
                public String getLabel() {
                    return alabel+blabel;
                }

                @Override
                public boolean isLabelShown() {
                    return false;
                }

                @Override
                public Set<PrimitiveObject> getPrimitiveObjects() {
                    return segset;
                }

                @Override
                public String getStepDescription() {
                    return "<"+SegmentPlugin.this.getPluginName()+"> "
                            +this.getLabel()+
                            ", |"+this.getLabel()+"| = "+(new Double(length)).toString();
                }
            };
            ConstructionObject[] ret = {XY, X, Y};
            return ret;
        }
        return null;
    }
    
    @Override
    public String getError(){
        return error;
    }
    
    private class TwoPointsParameters extends InputParameters{

        @Override
        public String getParametersCaption() {
            return "Dva body";
        }

        @Override
        public ParameterItem[] getParameters() {
            ParameterItem[] params = new ParameterItem[2];
            params[0] = new ParameterObject() {

                @Override
                public String getCaption() {
                    return "A";
                }

                @Override
                public String[] getObjectNames() {
                    String[] str = {"Bod"};
                    return str;
                }
            };
            params[1] = new ParameterObject() {

                @Override
                public String getCaption() {
                    return "B";
                }

                @Override
                public String[] getObjectNames() {
                    String[] str = {"Bod"};
                    return str;
                }
            };
            return params;
        }
        
    }
    
    private class FirstSegmentParam extends InputParameters{

        @Override
        public int getMaxStepsToShow() {
            return 0;
        }

        @Override
        public int getMinStepsToShow() {
            return 0;
        }

        
        @Override
        public String getParametersCaption() {
            return "První úsečka";
        }

        @Override
        public ParameterItem[] getParameters() {
            ParameterItem[] params = new ParameterItem[5];
            params[0] = new ParameterString() {

                @Override
                public String getText() {
                    return "Jména nových krajních bodů:";
                }
            };
            params[1] = new ParameterValue() {

                @Override
                public String getCaption() {
                    return "1. bod";
                }
            };
            params[2] = new ParameterValue() {

                @Override
                public String getCaption() {
                    return "2. bod";
                }
            };
            params[3] = new ParameterString() {

                @Override
                public String getText() {
                    return "Délka úsečky:";
                }
            };
            params[4] = new ParameterValue() {

                @Override
                public String getCaption() {
                    return "Délka";
                }
            };
            return params;
        }
        
    }
    
}
